package com.cdpm.web.controller.system;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cdpm.common.config.CdpmConfig;
import com.cdpm.common.core.domain.model.LoginUser;
import com.cdpm.common.utils.SecurityUtils;
import com.cdpm.framework.config.ServerConfig;
import com.cdpm.system.domain.WorkUpload;
import com.cdpm.system.domain.vo.FileVO;
import com.cdpm.system.service.ISysWorkUploadService;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.validation.constraints.NotNull;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author WeiHongBin
 */
@RestController
@RequestMapping("/upload")
@Api(value = "上传文件", tags = {"上传文件"})
@Slf4j
public class UploadController {

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private ISysWorkUploadService workUploadService;

    @ApiOperation("文件上传，附加操作人")
    @PostMapping
    public List<FileVO> upload(@Validated @NotNull MultipartFile files) {
        String originalFilename = files.getOriginalFilename();
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String code = loginUser.getUserId().toString();
        assert originalFilename != null;
        String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        String key = IdUtil.fastSimpleUUID() + "." + suffix;
        try {
            files.transferTo(new File(CdpmConfig.getUploadPath() + key));
        } catch (IOException e) {
            throw new RuntimeException("文件上传失败");
        }
        if(StringUtils.isNotEmpty(code)){
            WorkUpload workUpload = new WorkUpload();
            workUpload.setCreateUser(code);
            workUpload.setImageUrl(key);
            workUpload.setCreateTime(LocalDateTime.now());
            workUploadService.save(workUpload);
        }
        return new ArrayList<FileVO>() {{
            add(new FileVO() {{
                setUrl(serverConfig.getUrl() + "/upload/" + key);
            }});
        }};
    }

    @GetMapping("/{imageName}")
    public ResponseEntity<Resource> getImageUrl(@PathVariable String imageName) {
        log.info("getImageUrl-start and image name is : "+imageName);

        try {
            File imageFile = new File(CdpmConfig.getUploadPath() + imageName);
            if (!imageFile.exists()) {
                return ResponseEntity.notFound().build();
            }

            Resource resource = new FileSystemResource(imageFile);
            String contentType = getContentType(imageName);

            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType))
                    .body(resource);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    private String getContentType(String fileName) {
        if (fileName.endsWith(".png")) {
            return "image/png";
        } else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
            return "image/jpeg";
        } else if (fileName.endsWith(".gif")) {
            return "image/gif";
        } else {
            return "application/octet-stream";
        }
    }

    @GetMapping("/files")
    public String files(@RequestParam("_limit") String _limit,@RequestParam("_start") String _start){
        String jsonResponse = "";
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String code = loginUser.getUserId().toString();
        if(StringUtils.isNotEmpty(code)){
            // 创建 WorkUpload 实例并设置查询条件
            WorkUpload workUpload = new WorkUpload();
            workUpload.setCreateUser(code);

            // 创建 QueryWrapper 实例
            QueryWrapper<WorkUpload> queryWrapper = new QueryWrapper<>(workUpload);

            // 设置分页参数
            int currentPage = Integer.parseInt(_start) + 1; // 当前页码
            int pageSize = Integer.parseInt(_limit);   // 每页记录数

            // 创建分页对象
            Page<WorkUpload> page = new Page<>(currentPage, pageSize);

            // 执行分页查询
            IPage<WorkUpload> resultPage = workUploadService.page(page, queryWrapper);

            // 获取查询结果
            List<WorkUpload> records = resultPage.getRecords();
            long total = resultPage.getTotal(); // 总记录数
            try {
                ObjectMapper objectMapper = new ObjectMapper();

                // Create an array to hold responses
                Map<String, Object>[] responses = new HashMap[records.size()];

                for (int j = 0; j < records.size(); j++) {
                    String fileName = records.get(j).getImageUrl();
                    File imageFile = new File(CdpmConfig.getUploadPath() + fileName);

                    if (!imageFile.exists()) {
                        responses[j] = createErrorResponse("File not found");
                        continue;
                    }

                    BufferedImage originalImage = ImageIO.read(imageFile);
                    int width = originalImage!=null?originalImage.getWidth():500;
                    int height = originalImage!=null?originalImage.getHeight():500;

                    Map<String, Object> response = new HashMap<>();
                    response.put("id", j + 1);
                    response.put("name", fileName);
                    response.put("alternativeText", null);
                    response.put("caption", null);
                    response.put("width", width);
                    response.put("height", height);
                    response.put("hash", generateHash(fileName));
                    response.put("ext", FilenameUtils.getExtension(fileName));
                    response.put("mime", "image/png");
                    response.put("size", FileUtils.sizeOf(imageFile) / 1024.0); // size in KB
                    response.put("url", serverConfig.getUrl() + "/upload/" + fileName);
                    response.put("created_at", LocalDateTime.now().toString());
                    response.put("updated_at", LocalDateTime.now().toString());
                    response.put("related", new String[]{});

                    responses[j] = response;
                }

                jsonResponse = objectMapper.writeValueAsString(responses);
            } catch (Exception e) {
                e.printStackTrace();

            }
        }

        return jsonResponse;
    }

    @GetMapping("/files/count")
    public String filesCount() {
        String jsonResponse = "";
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String code = loginUser.getUserId().toString();
        if (StringUtils.isNotEmpty(code)) {
            // 创建 WorkUpload 实例并设置查询条件
            WorkUpload workUpload = new WorkUpload();
            workUpload.setCreateUser(code);
            // 创建 QueryWrapper 实例
            QueryWrapper<WorkUpload> queryWrapper = new QueryWrapper<>(workUpload);
            if (workUploadService.list(queryWrapper) != null) {
                jsonResponse = workUploadService.list(queryWrapper).size() + "";
            }
        }
        return jsonResponse;
    }

    private static String generateHash(String filename) {
        return FilenameUtils.getBaseName(filename) + "_d57eb85422";
    }

    private static Map<String, Object> createErrorResponse(String errorMessage) {
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("error", errorMessage);
        return errorResponse;
    }


}